package com.isyscore.os.metadata.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.isyscore.device.common.model.RespDTO;
import com.isyscore.os.metadata.enums.KettleJobTriggerType;
import com.isyscore.os.metadata.kettle.dto.FlowDefinitionDTO;
import com.isyscore.os.metadata.kettle.dto.FlowDefinitionPageReqDTO;
import com.isyscore.os.metadata.model.dto.MetricListDTO;
import com.isyscore.os.metadata.model.dto.MetricResultDTO;
import com.isyscore.os.metadata.model.dto.req.MetricPageQuery;
import com.isyscore.os.metadata.model.entity.Metric;
import com.isyscore.os.metadata.service.DataFlowDefinitionService;
import com.isyscore.os.metadata.service.DataFlowTaskService;
import com.isyscore.os.metadata.service.ETLFlowTaskLogService;
import com.isyscore.os.metadata.service.impl.MetricService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author liy
 * @date 2022-10-20 17:11
 */

@RestController
@RequestMapping("${api-full-prefix}/etlflow/openApi")
@Api(tags = "UDMP OpenAPI")
@Slf4j
@RequiredArgsConstructor
public class OpenApiController {
    @Autowired
    private DataFlowTaskService dataFlowTaskService;
    @Autowired
    private DataFlowDefinitionService dataFlowDefinitionService;
    @Autowired
    private ETLFlowTaskLogService etlFlowTaskLogService;
    @Autowired
    private MetricService metricService;

    @ApiOperation("流程列表")
    @GetMapping("/flow/page")
    public RespDTO<IPage<FlowInfo>> flowPageDefinition(FlowDefinitionPageReqDTO pageRequest) {
        IPage<FlowDefinitionDTO> flowDefinitionDTOIPage = dataFlowDefinitionService.pageFlowDefinition(pageRequest);
        List<FlowInfo> list = new ArrayList<>();
        for (FlowDefinitionDTO record : flowDefinitionDTOIPage.getRecords()) {
            list.add(new FlowInfo(record.getDefinitionId(), record.getFlowName(), record.getDescription(),"/api/udmp/metadata/etlflow/task/start/"+record.getDefinitionId()));
        }
        Page<FlowInfo> flowInfoPage = new Page<>();
        BeanUtil.copyProperties(flowDefinitionDTOIPage, flowInfoPage);
        flowInfoPage.setRecords(list);
        return RespDTO.onSuc(flowInfoPage);
    }


    @ApiOperation("启动一个任务")
    @PostMapping("/flow/start/{definitionId}")
    public RespDTO<String> flowRunTask(@ApiParam(name = "definitionId", value = "流程定义ID", required = true) @PathVariable("definitionId") String definitionId,
                                   @ApiParam(name = "params", value = "启动任务时的动态参数", required = false) @RequestBody(required = false) Map<String, String> params,
                                   @ApiParam(name = "callbackUrl", value = "任务状态通知回调地址(需为POST类型的地址,body data部分数据按照这种结构返回{\"status\": \"\",\"message\": \"\"})", required = false) @RequestParam(name = "callbackUrl",required = false) String callbackUrl) {


        OpenApiController.CallBack callBack = new OpenApiController.CallBack();
        callBack.setUrl(callbackUrl);
        return RespDTO.onSuc(dataFlowTaskService.runTask(definitionId, params, KettleJobTriggerType.MANUAL, callBack));
    }

    @ApiOperation("停止运行中的任务")
    @GetMapping("/flow/stop/{taskId}")
    public RespDTO<String> flowKillTask(@PathVariable(value = "taskId")@ApiParam(name = "taskId", value = "任务ID", required = true) String taskId) {
        dataFlowTaskService.stopTask(taskId);
        return RespDTO.onSuc();
    }


    @ApiOperation("获取任务运行状态")
    @GetMapping("/flow/status/{taskId}")
    public RespDTO<String> flowStatus(@PathVariable(value = "taskId")@ApiParam(name = "taskId", value = "任务ID", required = true) String taskId) {
        return RespDTO.onSuc(dataFlowTaskService.taskStatus(taskId));
    }

    @ApiOperation("获取任务运行日志")
    @GetMapping("/flow/log/{taskId}")
    public RespDTO<String> flowLog(@PathVariable("taskId")@ApiParam(name = "taskId", value = "任务ID", required = true) String taskId) {

        return RespDTO.onSuc(etlFlowTaskLogService.getTaskRawLog(taskId));
    }


    @ApiOperation("指标定时计算任务的结果查询")
    @GetMapping("/metric/results/{metricId}")
    public RespDTO<List<MetricResultDTO>> getMetricResults(@PathVariable(value = "metricId")@ApiParam(name = "metricId", value = "指标ID", required = true) Long metricId,
                                                           @RequestParam(value = "timePeriod", required = false)@ApiParam(name = "timePeriod", value = "该指标对应的统计时间周期", required = false) String timePeriod,
                                                           @RequestParam(value = "dimOrder", required = false)@ApiParam(name = "dimOrder", value = "排序", required = false) String dimOrder,
                                                           @RequestParam(value = "dimension", required = false)@ApiParam(name = "dimension", value = "维度", required = false) String dimension) {
        List<MetricResultDTO> resultObj = metricService.queryMetricJobResultByPeriod(metricId, timePeriod, dimOrder, dimension);
        return RespDTO.onSuc(resultObj);
    }

    @ApiOperation("分页查询数据指标列表")
    @GetMapping("/metric/page")
    public RespDTO<IPage<MetricListDTO>> metricPage(MetricPageQuery pageQuery) {
        IPage<Metric> metrics = metricService.pageWithPageParam(pageQuery);
        IPage<MetricListDTO> pageData = metrics.convert((metric) -> {
            MetricListDTO listDto = new MetricListDTO();
            listDto.setId(metric.getId());
            listDto.setName(metric.getName());
            listDto.setGroupId(metric.getGroupRefId());
            listDto.setDescription(metric.getDescription());
            listDto.setCreateTime(metric.getCreateTime());
            return listDto;
        });
        return RespDTO.onSuc(pageData);
    }



    @Data
    public static class CallBack {
        private String url;



        @Override
        public String toString() {
            return "CallBack{" +
                    "url='" + url + '\'' +
                    '}';
        }
    }

    @Data
    public static class FlowInfo {
        @ApiModelProperty("流程ID")
        private String definitionId;
        @ApiModelProperty("流程名称")
        private String name;
        @ApiModelProperty("流程描述")
        private String description;
        @ApiModelProperty("流程API地址")
        private String api;

        public FlowInfo(String definitionId, String name, String description, String api) {
            this.definitionId = definitionId;
            this.name = name;
            this.description = description;
            this.api = api;
        }
    }

}
